package cc.minos.console
{
	//import cc.minos.components.HBox;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.KeyboardEvent;
	import flash.events.MouseEvent;
	import flash.text.TextField;
	import flash.text.TextFieldAutoSize;
	import flash.text.TextFormat;
	import flash.ui.Keyboard;
	
	/**
	 * ...
	 * @author Minos
	 */
	public class ConsoleViewer extends Sprite
	{
		private var colors:Vector.<String> = new <String>[ "000000" , "0055AA" , "FF8800" , "FF3300" , "BB0000" ];
		
		private var cwidth:Number; //宽度
		private var cheight:Number; //高度
		
		private var tempWidth:Number; //宽度
		private var tempHeight:Number; //高度
		
		private var titleHeight:Number = 24; //标题栏高度
		private var padding:Number = 5; //间隔
		
		private var _enabled:Boolean = true; //是否开启
		private var _autoScroll:Boolean = true; //自动滚动
		private var _log:String = ""; //输出字符
		
		private var background:Sprite; //背景
		private var titleBar:Sprite; //标题栏容器
		private var title:TextField; //标题
		private var controls:Sprite; //控制文本容器
		private var saveTf:TextField; //保存
		private var showTf:TextField; //折叠或展开
		private var autoTf:TextField; //自动滚动
		private var clearTf:TextField; //清除
		private var closeTf:TextField; //关闭
		private var tf:ConsoleTF; //输出文本
		
		private var scrollBar:Sprite;
		private var scrollBarWidth:Number = 0;
		
		public function ConsoleViewer( width:Number = 600 , height:Number = 200 )
		{
			
			this.cheight = height;
			this.cwidth = width;
			
			addChild( background = new Sprite );
			addChild( titleBar = new Sprite );
			titleBar.addChild( title = getLabel( "Console v" + ConsoleSettting.VERSION , ConsoleSettting.TITLE_COLOR ) );
			titleBar.addChild( controls = new Sprite );
			addChild( tf = new ConsoleTF );
			
			//set title tf
			title.x = padding;
			title.y = ( titleHeight - title.height ) * .5;
			//add console tf
			tf.text = "";
			tf.x = 5 , tf.y = titleHeight;
			
			//add control tfs
			controls.addChild( clearTf = getLabel( buildEvent( "clear" ) , ConsoleSettting.TITLE_COLOR ) );
			controls.addChild( saveTf = getLabel( buildEvent( "save" ) , ConsoleSettting.TITLE_COLOR ) );
			controls.addChild( showTf = getLabel( buildEvent( "hide" ) , ConsoleSettting.TITLE_COLOR ) );
			controls.addChild( autoTf = getLabel( buildEvent( "stop" ) , ConsoleSettting.TITLE_COLOR ) );
			controls.addChild( closeTf = getLabel( buildEvent( "close" ) , ConsoleSettting.TITLE_COLOR ) );
			var xpos:Number = 0;
			for ( var i:int = 0; i < controls.numChildren; i++ ) {
				controls.getChildAt( i ).x = xpos;
				xpos += (controls.getChildAt(i).width + 8);
			}
			controls.y = ( titleHeight - controls.height ) * .5;
			
			//
			addChild( scrollBar = new Sprite() );
			
			scrollBarWidth = scrollBar.width;
			
			//show
			draw();
			
			controls.addEventListener( MouseEvent.CLICK , onControlsClick );
			tf.addEventListener( KeyboardEvent.KEY_DOWN , onTfKeyDown );
		}
		
		private function onTfKeyDown( e:KeyboardEvent ):void
		{
			switch ( e.keyCode )
			{
				case Keyboard.DELETE: 
					clearText();
					break;
			}
		}
		
		private function onControlsClick( e:MouseEvent ):void
		{
			var tf:TextField = e.target as TextField;
			if ( tf == null )
				return;
			
			switch ( tf.text )
			{
				case "clear": 
					clearText();
					break;
				
				case "save": 
					Console.saveLog();
					break;
				
				case "hide": 
				case "show": 
					if ( showing )
					{
						showTf.htmlText = buildEvent( "show" );
						min();
					}
					else
					{
						showTf.htmlText = buildEvent( "hide" );
						max();
					}
					break;
				
				case "auto": 
				case "stop": 
					_autoScroll = !_autoScroll;
					autoTf.htmlText = _autoScroll ? buildEvent( "stop" ) : buildEvent( "auto" );
					break;
				
				case "close": 
					Console.toggle();
					break;
			}
		
		}
		
		public function min():void
		{
			if ( contains( tf ) )
				removeChild( tf )
			tempWidth = cwidth;
			tempHeight = cheight;
			cheight = titleHeight;
			draw();
		}
		
		public function max():void
		{
			addChild( tf );
			cheight = tempHeight;
			draw();
		}
		
		public function appendText( str:Object , level:int = 0 ):void
		{
			_log += str;
			tf.htmlText += buildColor( str.toString() , level );
			
			if ( autoScroll )
				tf.scrollV = tf.numLines;
		}
		
		public function clearText():void
		{
			_log = "";
			tf.text = "";
		}
		
		protected function draw():void
		{
			//
			background.graphics.clear();
			background.graphics.lineStyle( 1 , ConsoleSettting.BACKGROUND_BORDER_COLOR , 1 , true );
			background.graphics.beginFill( ConsoleSettting.BACKGROUND_COLOR , 1 );
			background.graphics.drawRect( 0 , 0 , cwidth , cheight );
			background.graphics.endFill();
			//title bar
			titleBar.graphics.clear();
			titleBar.graphics.beginFill( ConsoleSettting.TITLE_BACKGROUND_COLOR , 1 );
			titleBar.graphics.drawRect( 2 , 2 , cwidth - 4 , titleHeight - 4 );
			titleBar.graphics.endFill();
			//
			tf.width = cwidth - 2 * padding - scrollBarWidth;
			tf.height = cheight - titleHeight - padding;
			
			controls.x = cwidth - controls.width - padding;
			if ( stage )
				this.y = stage.stageHeight - this.height;
				
			
		}
		
		/**
		 * build a html
		 * @param	msg
		 * @param	level
		 * @return
		 */
		protected function buildColor( msg:Object , level:int = 0 ):String
		{
			return "<font color=\"#" + colors[ level ] + "\">" + msg + "</font>";
		}
		
		private function buildEvent( s:String ):String
		{
			return "<a href=\"event:" + s + "\" >" + s + "</a>";
		}
		
		private function getLabel( s:String , c:uint = 0 ):TextField
		{
			var t:TextField = new TextField();
			t.defaultTextFormat = new TextFormat( ConsoleSettting.font , 12 , c );
			t.autoSize = TextFieldAutoSize.LEFT;
			t.selectable = false;
			t.htmlText = s;
			return t;
		}
		
		public function get showing():Boolean
		{
			return contains( tf );
		}
		
		public function set enabled( value:Boolean ):void
		{
			_enabled = value;
		}
		
		public function get enabled():Boolean
		{
			return _enabled;
		}
		
		override public function set width( value:Number ):void
		{
			cwidth = value;
			draw();
		}
		
		override public function set height( value:Number ):void
		{
			cheight = value;
			draw();
		}
		
		public function get autoScroll():Boolean
		{
			return _autoScroll;
		}
		
		public function set autoScroll( value:Boolean ):void
		{
			_autoScroll = value;
		}
		
		public function getLog():String
		{
			return _log;
		}
	
	}

}